package com.sdleyou.treepro.common.service.impl;

import com.sdleyou.treepro.common.exception.ServiceException;
import com.sdleyou.treepro.common.model.convert.MapDO2MapVOConverter;
import com.sdleyou.treepro.common.model.convert.MapVO2MapDOConverter;
import com.sdleyou.treepro.common.model.dao.*;
import com.sdleyou.treepro.common.model.enums.ErrorCodeEnum;
import com.sdleyou.treepro.common.model.enums.MapShowEnum;
import com.sdleyou.treepro.common.model.utils.RandomUtil;
import com.sdleyou.treepro.common.model.vo.AreaVO;
import com.sdleyou.treepro.common.model.vo.MapVO;
import com.sdleyou.treepro.common.model.vo.RegionVO;
import com.sdleyou.treepro.common.service.MapManager;
import com.sdleyou.treepro.common.service.MongoPageManager;
import com.sdleyou.treepro.system.excel.Excel;
import com.sdleyou.treepro.system.excel.ExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MapManagerImpl implements MapManager {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private MongoPageManager mongoPageManager;

    @Override
    public MapVO createMap(MapVO mapVO) {
        //从mongodb查找已有数据
        Query query = new Query(Criteria.where("base_name").is(mapVO.getName()));
        MapDO mapDO = mongoTemplate.findOne(query, MapDO.class);
        if (mapDO != null) {
            throw new ServiceException(ErrorCodeEnum.E001.code(), "基地名称已存在");
        }
        MapDO newMapDO = MapVO2MapDOConverter.convert(mapVO);
        mongoTemplate.insert(newMapDO);
        return mapVO;
    }

    @Override
    public Page mapList(Integer pageNum, Integer pageSize, String keywords, Integer sort) {
        Query query = new Query();
        if (!StringUtils.isEmpty(keywords)) {
            Criteria c = Criteria.where("base_name").is(keywords);
            query.addCriteria(c);
        }
        Page<MapDO> page = mongoPageManager.pageQuery(query, MapDO.class, pageSize, pageNum);
        List<MapDO> mapDOList = page.getData();
        List<MapVO> mapVOList = mapDOList.stream().map(e -> MapDO2MapVOConverter.convert(e)).collect(Collectors.toList());
        return new Page<>(page.getPageNo(), page.getDataTotal(), page.getPageSize(), mapVOList);
    }

    @Override
    public void updateMap(String baseId, MapVO mapVO) {
        Query query = new Query(Criteria.where("base_id").is(baseId));
        MapDO mapDO = mongoTemplate.findOne(query, MapDO.class);
        if (mapDO == null) {
            throw new ServiceException(ErrorCodeEnum.E002.code(), "基地不存在");
        }
        Update update = new Update();
        if (!StringUtils.isEmpty(mapVO.getName())) {
            query = new Query(Criteria.where("base_name").is(mapVO.getName()));
            MapDO exist = mongoTemplate.findOne(query, MapDO.class);
            if (exist != null) {
                throw new ServiceException(ErrorCodeEnum.E001.code(), "基地名称已存在");
            }
            update.set("base_name", mapVO.getName());
        }
        if (!StringUtils.isEmpty(mapVO.getIcon())) {
            update.set("base_icon", mapVO.getIcon());
        }
        if (!StringUtils.isEmpty(mapVO.getImage())) {
            update.set("base_image", mapVO.getImage());
        }
        if (!StringUtils.isEmpty(mapVO.getIsShow())) {
            update.set("is_show", mapVO.getIsShow());
        }
        if (!StringUtils.isEmpty(mapVO.getStatus())) {
            update.set("status", mapVO.getStatus());
        }
        mongoTemplate.updateFirst(query, update, MapDO.class);
        return;
    }

    @Override
    public void createArea(String baseId, AreaVO areaVO) {
        Query query = new Query(Criteria.where("base_id").is(baseId));
        MapDO mapDO = mongoTemplate.findOne(query, MapDO.class);
        if (mapDO == null) {
            throw new ServiceException(ErrorCodeEnum.E002.code(), "基地不存在");
        }
        AreaDO areaDO = new AreaDO();
        areaDO.setBaseId(baseId);
        areaDO.setAreaId(RandomUtil.randomId());
        areaDO.setAreaName(areaVO.getAreaName());
        areaDO.setAreaIcon(areaVO.getAreaIcon());
        areaDO.setIsShow(MapShowEnum.HIDDEN.name());
        mongoTemplate.insert(areaDO);
        return;
    }

    @Override
    public void updateArea(String areaId, AreaVO areaVO) {
        Query query = new Query(Criteria.where("area_id").is(areaId));
        AreaDO areaDO = mongoTemplate.findOne(query, AreaDO.class);
        if (areaDO == null) {
            throw new ServiceException(ErrorCodeEnum.E003.code(), "区域不存在");
        }
        Update update = new Update();
        if (!StringUtils.isEmpty(areaVO.getAreaName())) {
            update.set("area_name", areaVO.getAreaName());
        }
        if (!StringUtils.isEmpty(areaVO.getAreaIcon())) {
            update.set("area_icon", areaVO.getAreaIcon());
        }
        if (!StringUtils.isEmpty(areaVO.getIsShow())) {
            update.set("is_show", areaVO.getIsShow());
        }
        mongoTemplate.updateFirst(query, update, AreaDO.class);
        return;
    }

    @Override
    public void createRegion(String areaId, RegionVO regionVO) {
        Query query = new Query(Criteria.where("area_id").is(areaId));
        AreaDO areaDO = mongoTemplate.findOne(query, AreaDO.class);
        if (areaDO == null) {
            throw new ServiceException(ErrorCodeEnum.E003.code(), "区域不存在");
        }
        Query queryTree = new Query(Criteria.where("tree_id").is(regionVO.getTreeId()));
        TreeDO treeDO = mongoTemplate.findOne(queryTree, TreeDO.class);
        if (treeDO == null) {
            throw new ServiceException(ErrorCodeEnum.E006.code(), ErrorCodeEnum.E006.getDescription());
        }
        RegionDO regionDO = new RegionDO();
        regionDO.setBaseId(areaDO.getBaseId());
        regionDO.setAreaId(areaDO.getAreaId());
        regionDO.setRegionId(RandomUtil.randomId());
        regionDO.setRegionName(regionVO.getRegionName());
        regionDO.setRegionType(regionVO.getRegionType());
        regionDO.setTreeId(regionVO.getTreeId());
        regionDO.setTreeName(treeDO.getTreeName());
        regionDO.setCompanyId(regionVO.getCompanyId());
        regionDO.setTreeSum(0);
        regionDO.setCurrentSum(0);
        regionDO.setIsShow(MapShowEnum.HIDDEN.name());
        regionDO.setLatitude(regionVO.getLatitude());
        regionDO.setLongitude(regionVO.getLongitude());
        Date date = new Date();
        regionDO.setGmtCreate(date.getTime());
        regionDO.setGmtModified(date.getTime());
        mongoTemplate.insert(regionDO);
        return;
    }

    @Override
    public void updateRegion(String regionId, RegionVO regionVO) {
        Query query = new Query(Criteria.where("region_id").is(regionId));
        RegionDO regionDO = mongoTemplate.findOne(query, RegionDO.class);
        if (regionDO == null) {
            throw new ServiceException(ErrorCodeEnum.E004.code(), "植树区不存在");
        }
        Update update = new Update();
        if (!StringUtils.isEmpty(regionVO.getRegionName())) {
            update.set("region_name", regionVO.getRegionName());
        }
        if (!StringUtils.isEmpty(regionVO.getRegionType())) {
            update.set("region_type", regionVO.getRegionType());
        }
        if (!StringUtils.isEmpty(regionVO.getCompanyId())) {
            update.set("company_id", regionVO.getCompanyId());
        }
        if (!StringUtils.isEmpty(regionVO.getIsShow())) {
            update.set("is_show", regionVO.getIsShow());
        }
        Date date = new Date();
        update.set("gmt_modified", date.getTime());
        mongoTemplate.updateFirst(query, update, RegionDO.class);
        return;
    }

    @Override
    public void importService(HttpServletRequest request, String regionId) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile excel = multipartRequest.getFile("filename");

        Query query = new Query(Criteria.where("region_id").is(regionId));
        RegionDO regionDO = mongoTemplate.findOne(query, RegionDO.class);
        if (regionDO == null) {
            throw new ServiceException(ErrorCodeEnum.E004.code(), "植树区不存在");
        }
        try {
            List<Excel> excelData = ExcelUtil.readExcelObject(excel, Excel.class);
            //初始总导入数量
            int amount = 0;
            //遍历excel，将坑位数据写入mongo
            for (int i = 0; i < excelData.size(); i++) {
                WellDO wellDO = new WellDO();
                wellDO.setBaseId(regionDO.getBaseId());
                wellDO.setAreaId(regionDO.getAreaId());
                wellDO.setRegionId(regionId);
                wellDO.setWellId(RandomUtil.randomId());
                wellDO.setWellName(excelData.get(i).getName());
                wellDO.setStatus(excelData.get(i).getStatus());
                wellDO.setIsFinish(false);
                wellDO.setPreTreeId(regionDO.getTreeId());
                wellDO.setPreTreeName(regionDO.getTreeName());
                wellDO.setOrderStatus(0);
                mongoTemplate.insert(wellDO);
                amount++;
            }
            //更新区域内树木总量
            Update update = new Update();
            update.set("tree_sum", regionDO.getTreeSum() + amount);
            mongoTemplate.updateFirst(query, update, RegionDO.class);
            return;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}
